package progetto;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;

import example.hot.InetCoordinates;

import peersim.config.Configuration;
import peersim.core.CommonState;
import peersim.core.Network;
import peersim.core.Node;
import peersim.graph.Graph;
import peersim.reports.GraphObserver;
import peersim.util.FileNameGenerator;

/**
 * This class prints to files the topology wiring using a Gnuplot friendly
 * syntax. Uses the {@link peersim.graph.Graph} interface to visit the topology.
 * 
 * @author Gian Paolo Jesi
 */
public class InfectionObserver extends GraphObserver {
    // ------------------------------------------------------------------------
    // Parameters
    // ------------------------------------------------------------------------

    /**
     * The filename base to print out the topology relations.
     * 
     * @config
     */
    private static final String PAR_FILENAME_BASE = "file_infection";
    
    /**
     * 
     * @config
     */
    private static final String PAR_STATUS_PROT = "protocol";
    // ------------------------------------------------------------------------
    // Fields
    // ------------------------------------------------------------------------

   
    /**
     * Topology filename. Obtained from config property
     * {@link #PAR_FILENAME_BASE}.
     */
    private final String infFileName;

    /**
     * Utility class to generate incremental indexed filenames from a common
     * base given by {@link #graph_filename}.
     */
    private final FileNameGeneratorExt fng;
    
    /**
     * Status protocol identifier. Obtained from config property
     * {@link #PAR_STATUS_PROT}.
     */
    private final int statusPid;
    
    private final String fileName;

    // ------------------------------------------------------------------------
    // Constructorin
    // ------------------------------------------------------------------------
    /**
     * Standard constructor that reads the configuration parameters. Invoked by
     * the simulation engine.
     * 
     * @param prefix
     *            the configuration prefix for this class.
     */
    public InfectionObserver(String prefix) {
        super(prefix);
        statusPid = Configuration.getPid(prefix + "." + PAR_STATUS_PROT);
        infFileName = Configuration.getString(prefix + "."
                + PAR_FILENAME_BASE, "inf");
       
        fng = new FileNameGeneratorExt(infFileName, ".dat");
        //fileName = fng.nextTimerName();
        fileName = fng.nextSeedName();
    }

    // Control interface method.
    public boolean execute() {
    	
    	boolean allInfected = false;
        try {
            updateGraph();

            System.out.print(name + ": ");
            
            
            
            
            //read the file
            
            File f = new File(fileName);
            if(!f.exists()) {
            	//create the file
            	f.createNewFile();
            }
            
            FileOutputStream fos = new FileOutputStream(fileName, true);
            System.out.println("Writing to file " + fileName);
            PrintStream ps = new PrintStream(fos);
        

            // initialize output streams
            
            
            
            allInfected = graphToFile(g, ps, statusPid);

            fos.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return allInfected;
    }

    /**
     * Utility method: prints out data to plot the topology using gnuplot a
     * gnuplot style.
     * 
     * @param g
     *            current graph.
     * @param ps_mobility
     *            a {@link java.io.PrintStream} object to write to.
     * @param coordPid
     *            coordinate protocol identifier.
     * @param statusPid
     *            status protocol identifier.
     */
    private static boolean graphToFile(Graph g, PrintStream ps, int statusPid) {
    	int infNodes = 0;
    	int currentRun = CommonState.getIntTime();
        for (int i = 0; i < g.size(); i++) {
            Node current = (Node) g.getNode(i);
           
            boolean flagInfected =  ((NodeStatus)current.getProtocol(statusPid)).isInfected();
            if(flagInfected) {
            	infNodes++;
            }
            
     
        }
           
       
        double fractionInfNodes = (double)infNodes/(double)Network.size();

        ps.append(fractionInfNodes + " "+ currentRun+ "\n");   

        if(fractionInfNodes==1)
        	return true;
        return false;

    }
}
